package com.lzj.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lzj.admin.model.CountResultModel;
import com.lzj.admin.pojo.*;
import com.lzj.admin.mapper.SaleListMapper;
import com.lzj.admin.query.SaleListQuery;
import com.lzj.admin.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lzj.admin.utils.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 销售单表 服务实现类
 * </p>
 *
 * @author luoyoumou
 * @date 2022-12-15
 */
@Service
public class SaleListServiceImpl extends ServiceImpl<SaleListMapper, SaleList> implements ISaleListService {

    @Resource
    private IGoodsService goodsService;

    @Resource
    private ISaleListGoodsService saleListGoodsService;

    @Resource
    private IGoodsTypeService goodsTypeService;

    @Resource
    private ICustomerService customerService;

    @Resource ISaleListPaymentService saleListPaymentService;

    @Override
    public String getNextSaleNumber() {
        try {
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append("XS");
            stringBuffer.append(DateUtil.getCurrentDateStr());
            String saleNumber = this.baseMapper.getNextSaleNumber();
            if (null != saleNumber) {
                stringBuffer.append(StringUtil.formatCode(saleNumber));
            } else {
                stringBuffer.append("0001");
            }
            return stringBuffer.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void saveSaleList( SaleList saleList, List<SaleListGoods> slgList) {
        AssertUtil.isTrue(null == saleList.getCustomerId() ,"请选择客户！");
        Customer customer = customerService.getById(saleList.getCustomerId());
        AssertUtil.isTrue( null == customer,"客户不存在！");
        AssertUtil.isTrue(CollectionUtils.isEmpty(slgList),"请添加商品！");
        // BigDecimal.valueOf(0).compareTo(customerReturnList.getAmountPaid())>-1
        // AssertUtil.isTrue(null == saleList.getAmountPaid() || 0 > saleList.getAmountPaid() ,"必须满足：实付金额 >=0 ！");
        AssertUtil.isTrue(null == saleList.getAmountPaid() || BigDecimal.valueOf(0).compareTo(saleList.getAmountPaid())==1 ,"必须满足：实付金额 >= 0 ！");
        // AssertUtil.isTrue( saleList.getAmountPaid() > saleList.getAmountPayable() ,"必须满足：实付金额 <= 应付金额 ！");
        AssertUtil.isTrue( saleList.getAmountPaid().compareTo(saleList.getAmountPayable())==1 ,"必须满足：实付金额 <= 应付金额 ！");
        AssertUtil.isTrue(BigDecimal.ZERO.compareTo(saleList.getAmountDiscounts())==1,"必须满足：优惠金额 >= 0 !");
        if(BigDecimal.ZERO.compareTo(saleList.getAmountDiscounts())==-1){ // 如果优惠金额 大于 0
            AssertUtil.isTrue(!(saleList.getAmountPayable().compareTo(saleList.getAmountPaid().add(saleList.getAmountDiscounts()))==0) ,"必须满足：实付金额 + 优惠金额 = 应付金额 ！");
            // 实付金额 >= 优惠金额
            AssertUtil.isTrue(saleList.getAmountPaid().compareTo(saleList.getAmountDiscounts()) < 1,"挣钱不容易，不要卖血；必须满足：实付金额 >= 优惠金额 ！");
        }
        Date updateDate = new Date();
        saleList.setCreateDate(updateDate);
        saleList.setUpdateDate(updateDate);
        saleList.setIsDel(0);
        AssertUtil.isTrue(!(this.save(saleList)), "记录添加失败!");
        SaleList tempSaleList = this.getOne(new QueryWrapper<SaleList>().eq("sale_number", saleList.getSaleNumber()));

        // 添加销售商品明细 & 同时 减商品库存
        slgList.forEach(slg -> {
            AssertUtil.isTrue(null == slg.getNum()|| 1 > slg.getNum(),"请检查：每件商品的 数量 必须 >= 1 ！");
            slg.setSaleListId(tempSaleList.getId());
            slg.setFpyName(PinYinUtil.getFirstSpell(slg.getName()));
            Goods goods = goodsService.getById(slg.getGoodsId());
            // 检查库存
            AssertUtil.isTrue(goods.getInventoryQuantity()< slg.getNum(),"商品 "+ goods.getName() +" 的库存数量不足，操作失败！");
            goods.setInventoryQuantity(goods.getInventoryQuantity() - slg.getNum());
            goods.setState(2);
            AssertUtil.isTrue(!(goodsService.updateById(goods)), "销售单记录添加失败-@1!");
            AssertUtil.isTrue(!(saleListGoodsService.save(slg)), "销售单记录添加失败-@2!");
        });

        // 更新客户 最后交易日期
        Date saleDate = saleList.getSaleDate();
        Date customerLastTradeDate = customer.getLastTradeDate();
        if(customerLastTradeDate.before(saleDate)){
            customer.setLastTradeDate(updateDate);
            AssertUtil.isTrue(!(customerService.updateById(customer)), "销售单记录添加失败-@3!");
        }

        // if(saleList.getAmountPaid()>0){
        if(BigDecimal.valueOf(0).compareTo(saleList.getAmountPaid())==-1){
            SaleListPayment saleListPayment = new SaleListPayment();
            saleListPayment.setSaleListId(tempSaleList.getId());
            saleListPayment.setSaleNumber(tempSaleList.getSaleNumber());
            saleListPayment.setPayType(1);
            saleListPayment.setPayDate(tempSaleList.getSaleDate());
            saleListPayment.setAmountPaid(tempSaleList.getAmountPaid());
            saleListPayment.setAmountDiscounts(tempSaleList.getAmountDiscounts());
            saleListPayment.setUserId(tempSaleList.getUserId());
            saleListPayment.setUpdateUserId(tempSaleList.getUserId());
            saleListPayment.setCreateDate(tempSaleList.getCreateDate());
            saleListPayment.setUpdateDate(tempSaleList.getCreateDate());
            saleListPayment.setSaleNumber(tempSaleList.getSaleNumber());
            saleListPayment.setIsDel(0);
            AssertUtil.isTrue(!(saleListPaymentService.save(saleListPayment)), "销售单记录添加失败-@4!");
        }
    }

    @Override
    public Map<String, Object> saleList(SaleListQuery saleListQuery) {
        IPage<SaleList> page = new Page<SaleList>(saleListQuery.getPage(), saleListQuery.getLimit());
        page = this.baseMapper.saleList(page, saleListQuery);
        return PageResultUtil.getResult(page.getTotal(), page.getRecords());
    }

    /**
     * 商品销售统计,查总数，查当前页列表
     * @param saleListQuery
     * @return
     */
    @Override
    public Map<String, Object> countSale(SaleListQuery saleListQuery) {
        /**
         * 分页查询
         *   查总数
         *   查当前页列表
         */
        if(null !=saleListQuery.getTypeId()){
            List<Integer> typeIds= goodsTypeService.queryAllSubTypeIdsByTypeId(saleListQuery.getTypeId());
            saleListQuery.setTypeIds(typeIds);
        }
        if( null != saleListQuery.getTypeName()){
            saleListQuery.setTypeIds(goodsTypeService.queryAllSubTypeIdsByTypeId(saleListQuery.getTypeName()));
        }
        /**
         *  page
         *    1-->0
         *    2-->10
         *    3-->20
         */
        saleListQuery.setIndex((saleListQuery.getPage()-1)*saleListQuery.getLimit());
        Long count  = this.baseMapper.countSaleTotal(saleListQuery);
        List<CountResultModel> list =this.baseMapper.saleListQueryList(saleListQuery);
        return PageResultUtil.getResult(count,list);
    }

    @Override
    public List<Map<String, Object>> countDaySale(String begin, String end) {
        return this.baseMapper.countDaySale(begin,end);
    }

    @Override
    public List<Map<String, Object>> countMonthSale(String begin, String end) {
        return this.baseMapper.countMonthSale(begin,end);
    }

    /**
     * "已付款" 或 "部分付款" 的单据 不能被删除(只有未付款单据才能被删除)
     * 销售单据的删除 需要添加相关商品 到库存
     * @param id
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void deleteSaleList(Integer id,Integer userId) {
        SaleList saleList = this.getOne(new QueryWrapper<SaleList>().eq("id",id).eq("is_del", 0)); // .eq("state",0)
        AssertUtil.isTrue( null == saleList,"订单不存在！");
        AssertUtil.isTrue(!(saleList.getState()==0),"只有未付款订单才能被删除！");
        saleList.setUpdateUserId(userId);
        saleList.setUpdateDate(new Date());
        saleList.setIsDel(1);
        AssertUtil.isTrue(!(this.updateById(saleList)),"销售单记录删除失败-@1!");
        List<SaleListGoods> slgList = saleListGoodsService.getSaleListGoodsBySaleListId(id);
        slgList.forEach(slg -> {
            Goods goods = goodsService.getById(slg.getGoodsId());
            AssertUtil.isTrue( null == goods|| 1 == goods.getIsDel(),"记录删除失败：订单涉及的商品(商品Id: "+slg.getGoodsId()+") 已不存在，导致无法添加其库存！");
            goods.setInventoryQuantity(goods.getInventoryQuantity() + slg.getNum());
            AssertUtil.isTrue(!(goodsService.updateById(goods)), "销售单记录删除失败-@2!");
        });
    }

}
